package com.northpool.operator.cicd.ssh;

import cn.hutool.core.exceptions.ExceptionUtil;
import cn.hutool.core.io.FileUtil;
import com.jcraft.jsch.SftpProgressMonitor;
import com.northpool.operator.annotation.InputParam;
import com.northpool.operator.annotation.InputParams;
import com.northpool.operator.annotation.OperatorInfo;
import com.northpool.operator.common.algorithm.OperatorTestBuild;
import com.northpool.operator.common.algorithm.TestParamBuilder;
import com.northpool.operator.param.ParamTool;
import com.northpool.operator.type.TypeEnum;
import com.northpool.operator.utils.StpOperatorHelper;

@OperatorInfo(
        ref = "SshFileUploadOperator",
        name = "sftp文件上传",
        description = "ssh文件上传算子",
        version = "1.0.0"
)
public class SshFileUploadOperator extends StpOperatorHelper {

    @InputParams({
            @InputParam(ref = "host", name = "主机", desc = "主机IP或域名，如：10.80.9.11", required = true),
            @InputParam(ref = "port", name = "端口", desc = "SSH服务端口，如：22", value = "22", type = TypeEnum.NUMBER),
            @InputParam(ref = "user", name = "用户名", desc = "登录用户名，如：test", required = true),
            @InputParam(ref = "pass", name = "密码", desc = "登录密码，如：password", required = true, type = TypeEnum.SECRET),
            @InputParam(ref = "file", name = "文件路径", desc = "文件路径，如：/data/temp/test.txt", required = true),
            @InputParam(ref = "remotePath", name = "远程文件路径", desc = "远程文件路径，上传到指定路径，如：/data/temp/test.txt", required = true),
    })
    public SshFileUploadOperator() {
    }

    public static void main(String[] args) {
        OperatorTestBuild.execute(SshFileUploadOperator.class, TestParamBuilder.aBuilder()
                .param("host", "192.168.5.11")
                .param("port", "22")
                .param("user", "root")
                .param("pass", "950519")
                .param("file", "d:/temp/stp-jianmu.zip")
                .param("remotePath", "/root/")
                .build());
    }

    @Override
    public void execute(ParamTool paramTool) throws Exception {
        String host = paramTool.getStr("host");
        int port = paramTool.getNumber("port").intValue();
        String user = paramTool.getStr("user");
        String pass = paramTool.getStr("pass");
        String filePath = paramTool.getStr("file");
        String remotePath = paramTool.getStr("remotePath");

        JschUtils jschUtils = new JschUtils();
        long fileSize = FileUtil.size(FileUtil.file(filePath));
        try {
            jschUtils.connect(user, pass, host, port);
            jschUtils.upload(remotePath, filePath, new SftpProgressMonitor(){
                private long transferredLength = 0;
                private long logTime = System.currentTimeMillis();

                @Override
                public void init(int i, String src, String dest, long max) {
                    SshFileUploadOperator.this.log("开始上传: {}, 总大小: {}", filePath, fileSize);
                }

                @Override
                public boolean count(long count) {
                    transferredLength += count;
                    double percentTransferred = ((double) transferredLength / fileSize) * 100;
                    if (System.currentTimeMillis() - logTime > 3000) {
                        SshFileUploadOperator.this.log("上传进度: {}", percentTransferred);
                        logTime = System.currentTimeMillis();
                    }
                    return true;
                }

                @Override
                public void end() {
                    SshFileUploadOperator.this.log("上传完成");
                }
            });
            this.log("上传成功, 上传到路径: {}", remotePath);
        } catch (Exception e) {
            String stacktrace = ExceptionUtil.stacktraceToString(e);
            this.error("上传文件失败，错误堆栈: {}", stacktrace);
        } finally {
            jschUtils.close();
        }

    }
}
